package cx3k.dataaccess.search;

import java.lang.reflect.Field;
import java.util.Iterator;


public class SearchValue extends SearchNode {
	
	private String fieldName;
	private String value;
	private EqualityType operator;
	
	
	
	public SearchValue(String type, String field, String value, EqualityType operator, SearchNode parent){
		super(type);
		setFieldName(field);
		setValue(value);
		setOperator(operator);
		setParent(parent);
	}
	
	public SearchValue(Class<?> type, Field field, Object value, SearchNode parent){
		this(type, field, value, EqualityType.LIKE, parent);
	}
	
	public SearchValue(Class<?> type, Field field, Object value, EqualityType operator, SearchNode parent){
		super(type);
		setFieldName(field.getName());
		setValue(value.toString());
		setOperator(operator);
		setParent(parent);
	}
	
	protected String getFieldName(){
		return fieldName;
	}
	
	private void setFieldName(String fieldName){
		this.fieldName = fieldName;
	}
	
	
	protected String getValue(){
		return value;
	}
	
	protected EqualityType getOperator(){
		return operator;
	}
	
	
	@Override
	public String getDefaultQueryStr(){
		
		if(getChildren() == null || getChildren().isEmpty()){
			return getOperator().getNot() + getNickName() + "." + getFieldName() + getOperator().generateStatement(getValue());
		} else {
			StringBuffer ret = new StringBuffer();
			
			Iterator<SearchNode> iterateChild = getChildren().iterator();
			
//			ret.append("(" + iterateChild.next().getDefaultQueryStr());
			ret.append("(" + getOperator().getNot() + getNickName() + "." + getFieldName() + getOperator().generateStatement(getValue()));
			
			while(iterateChild.hasNext()){
				ret.append(iterateChild.next().getDefaultQueryStr());
			}
			
			ret.append(")");
			
			return ret.toString();
		}
		
		
	}
	
	private void setValue(String value){
		this.value = value;
	}
	
	private void setOperator(EqualityType operator){
		this.operator = operator;
	}
	
	

	public boolean equals(Object obj){
		try{
			
			SearchValue other = (SearchValue) obj;
			
			return this.getOperator().equals(other.getOperator()) &&
				   this.getValue().equals(other.getValue());
			
		} catch(ClassCastException e){
			return false;
		}
	}
	
	public enum EqualityType {
		EQUALS			(" = ", "'", "'"),
		LIKE			(" like ", "'%", "%'"),
		GREATER_THAN	(" > ", "'", "'"),
		LESS_THAN		(" < ", "'", "'"),
		NOT_LIKE		(" not ", " like ", "'%", "%'");
		
		private String not = "";
		private String operator;
		private String before;
		private String after;
		
		private EqualityType(String operator){
			this(operator, "", "");
		}
		
		private EqualityType(String operator, String before, String after){
			setOperator(operator);
			setBefore(before);
			setAfter(after);
		}
		
		private EqualityType(String not, String operator, String before, String after){
			this(operator, before, after);
			this.not = not;
		}
		
		public String getNot(){
			return not;
		}
		
		public String getOperator(){
			return operator;
		}
		
		public String getBefore(){
			return before;
		}
		
		public String getAfter(){
			return after;
		}
		
		protected String generateStatement(String value){
			return getOperator() + getBefore() + value + getAfter();
		}
		
		private void setOperator(String operator){
			this.operator = operator;
		}
		
		private void setBefore(String before){
			this.before = before;
		}
		
		private void setAfter(String after){
			this.after = after;
		}
		
	}
}
